#include "aurora_music.h"
#include "ui_aurora_music.h"
#include <QMouseEvent>
#include <QGraphicsDropShadowEffect>
#include <QList>
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QSqlError>
#include "commonpage.h"
#include <QPixmap>
#include <QSqlQuery>
#include <QSystemTrayIcon>
#include <QMenu>

aurora_music::aurora_music(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::aurora_music)
    ,currentIndex(4)
{
    ui->setupUi(this);
    initUI();
    initPlayer();
    initSQLite();
    initMusicList();
    connectSignalAndSlot();
    srand(time(NULL));
    ui->recMusictextBox->initRecBoxUi(RandomPicture(), 1);
    ui->supplyMusictextBox->initRecBoxUi(RandomPicture(), 2);
}

aurora_music::~aurora_music()
{
    delete ui;
}

void aurora_music::initUI()
{
    setWindowIcon(QIcon(":/images/tubiao.png"));
    ui->max->setEnabled(false);
    setWindowFlag(Qt::WindowType::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground);
    QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(this);
    shadowEffect->setOffset(0,0);
    shadowEffect->setColor("#000000");
    shadowEffect->setBlurRadius(10);
    this->setGraphicsEffect(shadowEffect);
    volumeTool = new VolumeTool(this);

    ui->rec->seticon(":/images/rec.png", "推荐", 1);
    ui->music->seticon(":/images/music.png", "音乐馆", 2);
    ui->audio->seticon(":/images/radio.png", "电台", 3);
    ui->like->seticon(":/images/like.png", "我喜欢", 4);
    ui->local->seticon(":/images/local.png", "本地下载", 5);
    ui->recent->seticon(":/images/recent.png", "最近播放", 6);
    ui->stackedWidget->setCurrentIndex(4);
    currentPage = ui->localPage;

    ui->likePage->setCommonPageUI("我喜欢", ":/images/ilikebg.png");
    ui->localPage->setCommonPageUI("本地⾳乐", ":/images/localbg.png");
    ui->recentPage->setCommonPageUI("最近播放", ":/images/recentbg.png");

    ui->play->setIcon(QIcon(":/images/play_2.png")); // 默认为暂停图标
    ui->playMode->setIcon(QIcon(":/images/shuffle_2.png")); // 默认为随机播放

    // 实例化LrcWord对象
    lrcPage = new LrcPage(this);
    lrcPage->setGeometry(10, 10, lrcPage->width(), lrcPage->height());
    lrcPage->hide();
    // lrcPage添加动画效果
    lrcAnimation = new QPropertyAnimation(lrcPage, "geometry", this);
    lrcAnimation->setDuration(250);
    lrcAnimation->setStartValue(QRect(10, 10 + lrcPage->height(),lrcPage->width(), lrcPage->height()));
    lrcAnimation->setEndValue(QRect(10, 10, lrcPage->width(), lrcPage->height()));

    // 添加托盘
    // 创建托盘图标
    QSystemTrayIcon *trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(QIcon(":/images/tubiao.png"));
    // 创建托盘菜单
    QMenu *trayMenu = new QMenu(this);
    trayMenu->addAction("还原", this, &QWidget::showNormal);
    trayMenu->addSeparator();
    trayMenu->addAction("退出", this, &aurora_music::quitQQMusic);
    // 将托盘菜单添加到托盘图标
    trayIcon->setContextMenu(trayMenu);
    // 显⽰托盘
    trayIcon->show();

}

QJsonArray aurora_music::RandomPicture()
{
    QVector<QString> vecImageName;
    vecImageName<<"001.png"<<"003.png"<<"004.png"<<"005.png"<<"006.png"
                <<"007.png"<<"008.png"<<"009.png"<<"010.png"<<"011.png"
                <<"012.png"<<"013.png"<<"014.png"<<"015.png"<<"016.png"
                <<"017.png"<<"018.png"<<"019.png"<<"020.png"<<"021.png"
                <<"022.png"<<"023.png"<<"024.png"<<"025.png"<<"026.png"
                <<"027.png"<<"028.png"<<"029.png"<<"030.png"<<"031.png"
                <<"032.png"<<"033.png"<<"034.png"<<"035.png"<<"036.png"
                <<"037.png"<<"038.png"<<"039.png"<<"040.png";
    std::random_shuffle(vecImageName.begin(),vecImageName.end());
    QJsonArray objArray;
    for(int i = 0;i < vecImageName.size();i++)
    {
        QJsonObject obj;
        obj.insert("path", ":/images/rec/"+vecImageName[i]);
        QString strText = QString("推荐-%1").arg(i + 1, 3, 10, QChar('0'));
        obj.insert("text", strText);
        objArray.append(obj);
    }
    return objArray;
}

void aurora_music::onUpdateLikeMusic(bool isLike, QString musicId)
{
    auto it = musicList.findMusicById(musicId);
    if(it != musicList.end())
    {
    it->setIsLike(isLike);
    }
    ui->likePage->reFresh(musicList);
    ui->localPage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);
}

void aurora_music::initPlayer()
{
    player = new QMediaPlayer(this);
    playerList = new QMediaPlaylist(this);
    playerList->setPlaybackMode(QMediaPlaylist::Loop);
    player->setPlaylist(playerList);
    player->setVolume(20);
    connect(player, &QMediaPlayer::stateChanged, this,&aurora_music::onPlayStateChanged);
    connect(ui->playMode, &QPushButton::clicked, this,&aurora_music::onPlaybackModeCliked);
    connect(playerList, &QMediaPlaylist::playbackModeChanged, this,&aurora_music::onPlaybackModeChanged);
    connect(playerList,&QMediaPlaylist::currentIndexChanged,this,&aurora_music::onCurrentIndexChanged);
    connect(player, &QMediaPlayer::durationChanged, this,&aurora_music::onDurationChanged);
    connect(player, &QMediaPlayer::positionChanged, this,&aurora_music::onPositionChanged);
    connect(player, &QMediaPlayer::metaDataAvailableChanged, this, &aurora_music::onMetaDataAvailableChangedChanged);
}

void aurora_music::setPlayerVolume(int vomume)
{
    player->setVolume(vomume);
}

void aurora_music::onBtFormClick(int id)
{
    QList<btForm*> buttonList = this->findChildren<btForm*>();
    foreach(btForm* btitem , buttonList)
    {
        if(id != btitem->getId())
        {
            btitem->clearBg();
        }
    }
    ui->stackedWidget->setCurrentIndex(id - 1);
    isDrag = false;
}

void aurora_music::connectSignalAndSlot()
{
    connect(ui->rec, &btForm::click, this, &aurora_music::onBtFormClick);
    connect(ui->music, &btForm::click, this, &aurora_music::onBtFormClick);
    connect(ui->audio, &btForm::click, this, &aurora_music::onBtFormClick);
    connect(ui->like, &btForm::click, this, &aurora_music::onBtFormClick);
    connect(ui->local, &btForm::click, this, &aurora_music::onBtFormClick);
    connect(ui->recent, &btForm::click, this, &aurora_music::onBtFormClick);
    connect(ui->likePage, &CommonPage::updateLikeMusic, this,&aurora_music::onUpdateLikeMusic);
    connect(ui->localPage, &CommonPage::updateLikeMusic, this,&aurora_music::onUpdateLikeMusic);
    connect(ui->recentPage, &CommonPage::updateLikeMusic, this,&aurora_music::onUpdateLikeMusic);
    connect(ui->play,&QPushButton::clicked,this,&aurora_music::onPlayCliked);
    connect(ui->playUp, &QPushButton::clicked, this,&aurora_music::onPlayUpCliked);
    connect(ui->playDown, &QPushButton::clicked, this,&aurora_music::onPlayDownCliked);
    connect(ui->likePage, &CommonPage::playAll, this, &aurora_music::onPlayAll);
    connect(ui->localPage, &CommonPage::playAll, this, &aurora_music::onPlayAll);
    connect(ui->recentPage, &CommonPage::playAll, this, &aurora_music::onPlayAll);
    connect(ui->likePage, &CommonPage::playMusicByIndex, this,&aurora_music::playMusicByIndex);
    connect(ui->localPage, &CommonPage::playMusicByIndex, this,&aurora_music::playMusicByIndex);
    connect(ui->recentPage, &CommonPage::playMusicByIndex, this,&aurora_music::playMusicByIndex);
    connect(volumeTool,&VolumeTool::setSilence,this,&aurora_music::setMusicSilence);
    connect(volumeTool,&VolumeTool::setMusicVolume,this,&aurora_music::setPlayerVolume);
    connect(ui->processBar, &MusicSlider::setMusicSliderPosition, this,&aurora_music::onMusicSliderChanged);
    connect(ui->lrcWord, &QPushButton::clicked, this,&aurora_music::onLrcWordClicked);
}

void aurora_music::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        isDrag = true;
        dragPosition = event->globalPos() - frameGeometry().topLeft();
        return;
    }
    QWidget::mousePressEvent(event);
}

void aurora_music::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() == Qt::LeftButton && isDrag)
    {
        move(event->globalPos() - dragPosition);
        return;
    }
    QWidget::mouseMoveEvent(event);
}


void aurora_music::on_quit_clicked()
{
    hide();
}

void aurora_music::on_volume_clicked()
{
    // 1. 获取该按钮左上⻆的图标
    QPoint point = ui->volume->mapToGlobal(QPoint(0,0));
    // 2. 计算volume窗⼝的左上⻆位置
    // 让该窗⼝显⽰在⿏标点击的正上⽅
    // ⿏标位置：减去窗⼝宽度的⼀半，以及⾼度恰巧就是窗⼝的左上⻆
    QPoint volumeLeftTop = point - QPoint(volumeTool->width()/2, volumeTool->height());
    // 微调窗⼝位置
    volumeLeftTop.setY(volumeLeftTop.y()+30);
    volumeLeftTop.setX(volumeLeftTop.x()+15);
    // 3. 移动窗⼝位置
    volumeTool->move(volumeLeftTop);
    // 4. 将窗⼝显⽰出来
    volumeTool->show();
}

void aurora_music::on_addLocal_clicked()
{
    QFileDialog file(this);
    file.setWindowTitle("添加本地音乐");
    file.setWindowIcon(QIcon(":/images/tubiao.png"));
    file.setOption(QFileDialog::DontUseNativeDialog, true);
    file.setAcceptMode(QFileDialog::AcceptOpen);
    file.setFileMode(QFileDialog::ExistingFiles);
    QStringList mimeList;
    mimeList<<"application/octet-stream";
    file.setMimeTypeFilters(mimeList);
    QDir dir(QDir::currentPath());
    dir.cdUp();
    QString path = dir.path() + "/aurora-music-player/musics";
    file.setDirectory(path);
    if(file.exec() == QFileDialog::Accepted)
    {
        ui->stackedWidget->setCurrentIndex(4);
        QList<QUrl> urls = file.selectedUrls();
        musicList.addMusicByUrl(urls);
        ui->localPage->reFresh(musicList);
    }
    playAllOfCommonPage(ui->localPage,0);
    player->stop();
}

void aurora_music::onPlayCliked()
{
    qDebug() <<"播放按钮点击";
    qDebug() <<player->state();
    if(player->state() == QMediaPlayer::PlayingState)
    {
        player->pause();
    }
    else if(player->state() == QMediaPlayer::PausedState)
    {
        qDebug() <<"开始播放";
        player->play();
    }
    else if(player->state() == QMediaPlayer::StoppedState)
    {
        qDebug() <<"开始播放";
        player->play();
    }
//     qDebug() <<player->state();
}

void aurora_music::onPlayStateChanged()
{
    qDebug()<<"播放状态改变";
    if(player->state() == QMediaPlayer::PlayingState)
    {
        // 播放状态
        ui->play->setIcon(QIcon(":/images/play_on.png"));
    }
    else
    {
        // 暂停状态
        ui->play->setIcon(QIcon(":/images/play3.png"));
    }
}

void aurora_music::onPlayUpCliked()
{
    playerList->previous();
}

void aurora_music::onPlayDownCliked()
{
    playerList->next();
}

void aurora_music::onPlaybackModeCliked()
{
    if(playerList->playbackMode() == QMediaPlaylist::Loop)
    {
    // 列表循环
        ui->playMode->setToolTip("随机播放");
        playerList->setPlaybackMode(QMediaPlaylist::Random);
    }
    else if(playerList->playbackMode() == QMediaPlaylist::Random)
    {
    // 随机播放
        ui->playMode->setToolTip("单曲循环");
        playerList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    }
    else if(playerList->playbackMode() == QMediaPlaylist::CurrentItemInLoop)
    {
        ui->playMode->setToolTip("列表循环");
        playerList->setPlaybackMode(QMediaPlaylist::Loop);
    }
    else
    {
        qDebug()<<"播放模式错误";
    }
}

void aurora_music::onPlaybackModeChanged(QMediaPlaylist::PlaybackMode playbackMode)
{
    if(playbackMode == QMediaPlaylist::Loop)
    {
        ui->playMode->setIcon(QIcon(":/images/list_play.png"));
    }
    else if(playbackMode == QMediaPlaylist::Random)
    {
        ui->playMode->setIcon(QIcon(":/images/shuffle_2.png"));
    }
    else if(playbackMode == QMediaPlaylist::CurrentItemInLoop)
    {
        ui->playMode->setIcon(QIcon(":/images/single_play.png"));
    }
    else
    {
        qDebug()<<"暂不⽀持该模式";
    }
}

void aurora_music::onPlayAll(PageType pageType)
{
    CommonPage* page = nullptr;
    switch(pageType)
    {
        case PageType::LIKE_PAGE:
        page = ui->likePage;
        break;
        case PageType::LOCAL_PAGE:
            page = ui->localPage;
            break;
        case PageType::HISTORY_PAGE:
            page = ui->recentPage;
            break;
        default:
            qDebug()<<"扩展";
    }
    playAllOfCommonPage(page,0);
}

void aurora_music::playAllOfCommonPage(CommonPage *commonPage, int index)
{
    currentPage = commonPage;
    playerList->clear();
    commonPage->addMusicToPlayer(musicList,playerList);
    playerList->setCurrentIndex(index);
    player->play();
}

void aurora_music::playMusicByIndex(CommonPage *page, int index)
{
    playAllOfCommonPage(page, index);
}

void aurora_music::onCurrentIndexChanged(int index)
{
    currentIndex = index;
    const QString& id = currentPage->getMusicIdByIndex(index);
    auto it = musicList.findMusicById(id);
    if(it != musicList.end())
    {
        it->setIsHistory(true);
    }
    ui->recentPage->reFresh(musicList);
}

void aurora_music::setMusicSilence(bool isMuted)
{
    player->setMuted(isMuted);
}

void aurora_music::onDurationChanged(qint64 duration)
{
    ui->totalTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10,QChar('0'))
                           .arg(duration/1000%60,2,10,QChar('0')));
     totalTime = duration;
}

void aurora_music::onPositionChanged(qint64 duration)
{
    ui->currentTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10,QChar('0'))
                                             .arg(duration/1000%60,2,10,QChar('0')));
    ui->processBar->setStep((float)duration / (float)totalTime);

    if(playerList->currentIndex() >= 0)
    {
        lrcPage->showLrcWord(duration);
    }
}

void aurora_music::onMusicSliderChanged(float value)
{
    qint64 duration = (qint64)(totalTime * value);
    ui->currentTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10,QChar('0'))
                                                .arg(duration/1000%60, 2, 10,QChar('0')));
    player->setPosition(duration);
}

void aurora_music::onMetaDataAvailableChangedChanged(bool available)
{
        (void)(available);
        // 歌曲名称、歌曲作者直接到Musci对象中获取
        // 此时需要知道媒体源在播放列表中的索引
        QString musicId = currentPage->getMusicIdByIndex(currentIndex);
        auto it = musicList.findMusicById(musicId);

        if(it != musicList.end())
        {
            lrcPage->parseLrc(it->getLrcFilePath());
        }

        QString musicName("未知歌曲");
        QString musicSinger("未知歌手");
        if(it != musicList.end())
        {
            musicName = it->getMusicName();
            musicSinger = it->getSingerName();
        }

        ui->musicName->setText(musicName);
        ui->musicSinger->setText(musicSinger);

        // 获取封面图，通过元数据来获取
        QVariant coverimage = player->metaData("ThumbnailImage");
        if(coverimage.isValid())
        {
            QImage image = coverimage.value<QImage>();
            ui->musicCover->setPixmap(QPixmap::fromImage(image));
            currentPage->setImageLabel(QPixmap::fromImage(image));
        }
        else
        {
            QString path = ":/images/rec/001.png";
            ui->musicCover->setPixmap(path);
            currentPage->setImageLabel(path);
        }
        ui->musicCover->setScaledContents(true);

}

void aurora_music::initSQLite()
{
    sqlite = QSqlDatabase::addDatabase("QSQLITE");
    sqlite.setDatabaseName("QQMusic.db");
    if(!sqlite.open())
    {
        QMessageBox::critical(this, "打开QQMusicDB失败",sqlite.lastError().text());
        return;
    }
    qDebug()<<"SQLite连接成功，并创建 [QQMusic.db] 数据库!!!";
    QString sql = ("CREATE TABLE IF NOT EXISTS musicInfo(\
        id INTEGER PRIMARY KEY AUTOINCREMENT,\
        musicId varchar(200) UNIQUE,\
        musicName varchar(50),\
        musicSinger varchar(50),\
        albumName varchar(50),\
        duration BIGINT,\
        musicUrl varchar(256),\
        isLike INTEGER,\
        isHistory INTEGER)"
    );
    QSqlQuery query;
    if(!query.exec(sql))
    {
        QMessageBox::critical(this, "创建数据库表失败",
        query.lastError().text());
        return;
    }
    qDebug()<<"创建 [musicInfo] 表成功!!!";
}

void aurora_music::initMusicList()
{
    // 1. 从数据库读取歌曲信息
    musicList.readFromDB();
    // 2. 更新CommonPage⻚⾯
    // 设置CommonPage的信息
    ui->likePage->setMusicListType(PageType::LIKE_PAGE);
    ui->likePage->reFresh(musicList);
    ui->localPage->setMusicListType(PageType::LOCAL_PAGE);
    ui->localPage->reFresh(musicList);
    ui->recentPage->setMusicListType(PageType::HISTORY_PAGE);
    ui->recentPage->reFresh(musicList);
}

void aurora_music::onLrcWordClicked()
{
    lrcPage->show();
    lrcAnimation->start();
}

void aurora_music::quitQQMusic()
{
    // 歌曲信息写⼊数据库
    musicList.writeToDB();
    // 断开与SQLite的链接
    sqlite.close();
    // 关闭窗⼝
    close();
}

void aurora_music::on_skin_clicked()
{
    QMessageBox::information(this, "温馨提⽰", "⼩哥哥正在加班紧急⽀持中...");
}

void aurora_music::on_min_clicked()
{
    showMinimized();
}
